package cn.tedu.lbs.marketing.web.service;

import cn.tedu.lbs.basic.api.BasicApi;
import cn.tedu.lbs.marketing.web.repository.ActivityRepository;
import cn.tedu.lbs.marketing.web.utils.AuthenticationContextUtil;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tarena.lbs.attach.api.AttachApi;
import com.tarena.lbs.base.common.utils.Asserts;
import com.tarena.lbs.base.protocol.exception.BusinessException;
import com.tarena.lbs.base.protocol.pager.PageResult;
import com.tarena.lbs.common.passport.principle.UserPrinciple;
import com.tarena.lbs.pojo.attach.dto.AttachDTO;
import com.tarena.lbs.pojo.attach.param.PicUpdateParam;
import com.tarena.lbs.pojo.attach.query.AttachQuery;
import com.tarena.lbs.pojo.basic.dto.AdminDTO;
import com.tarena.lbs.pojo.marketing.param.ActivityParam;
import com.tarena.lbs.pojo.marketing.po.ActivityPO;
import com.tarena.lbs.pojo.marketing.po.CouponPO;
import com.tarena.lbs.pojo.marketing.query.ActivityQuery;
import com.tarena.lbs.pojo.marketing.query.CouponQuery;
import com.tarena.lbs.pojo.marketing.vo.ActivityVO;
import com.tarena.lbs.pojo.marketing.vo.CouponVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ActivityService {
    @Autowired
    private ActivityRepository activityRepository;
    
    public PageResult<ActivityVO> pageList(ActivityQuery ActivityQuery) throws BusinessException {
        //1.拿到登录用户的id adminId
        Integer adminId = getUserId();
        //2.检查并获取 businessId
        Integer businessId = checkAndGetBusinessId(adminId);
        //3.利用businessId 查询该商家下的优惠券
        List<ActivityPO> pos= getActivitysByBusinessId(businessId);
        //4.封装分页(假的)返回
        return assemblePageResult(pos);
    }

    private PageResult<ActivityVO> assemblePageResult(List<ActivityPO> pos) {
        PageResult<ActivityVO> pageResult=new PageResult<>(10,1);
        pageResult.setTotal(100l);
        if (CollectionUtils.isNotEmpty(pos)){
            pageResult.setObjects(pos.stream().map(
                    po->{
                        ActivityVO vo=new ActivityVO();
                        BeanUtils.copyProperties(po,vo);
                        return vo;
                    }
            ).collect(Collectors.toList()));
        }else{
            pageResult.setObjects(null);
        }
        return pageResult;
    }
    private List<ActivityPO> getActivitysByBusinessId(Integer businessId) {
        //select * from activity where business_id=#{businessId}
        QueryWrapper<ActivityPO> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("business_id",businessId);
        return activityRepository.list(queryWrapper);
    }

    //dubbo调用
    @DubboReference
    private BasicApi basicApi;
    private Integer checkAndGetBusinessId(Integer adminId) throws BusinessException {
        AdminDTO dto = basicApi.getAdminDetail(adminId);
        Asserts.isTrue(dto==null,new BusinessException("-2","商家账号不存在"));
        return dto.getBusinessId();
    }

    private Integer getUserId() throws BusinessException {
        //读取 认证 传递的userPrinciple 线程和过滤器线程相同
        UserPrinciple userPrinciple = AuthenticationContextUtil.get();
        Asserts.isTrue(userPrinciple==null,new BusinessException("-2","用户认证解析失败"));
        return userPrinciple.getId();
    }

    public void save(ActivityParam param) throws BusinessException {
        //1.验证 认证对象 并且验证 商家账号 最后获取businessId
        Integer businessId=getBusinessId();
        //2.封装po对象 写入数据库 将写入成功的id返回
        Integer id=saveActivity(param,businessId);
        //3.调用图片服务绑定图片 bizType=700
        bindPicture(param,id);
    }
    @DubboReference
    private AttachApi attachApi;
    private void bindPicture(ActivityParam param, Integer id) {
        //1.明确的是入参 param中携带N张图片 都要绑定同一个活动id 都要绑定同一个业务类型 700
        String[] imgIds = param.getImgIds().split(",");
        //2.对数组每个元素 做map映射 List<PicUpdateParam> 绑定图片入参
        if (imgIds!=null&&imgIds.length>0){
            List<PicUpdateParam> params=Arrays.stream(imgIds).map(
                    imgId->{
                        PicUpdateParam picParam=new PicUpdateParam();
                        //imgId就是图片id id=bizId 700=bizType
                        picParam.setId(Integer.valueOf(imgId));
                        picParam.setBusinessId(id);
                        picParam.setBusinessType(700);
                        return picParam;
                    }
            ).collect(Collectors.toList());
            attachApi.batchUpdateBusiness(params);
        }
    }

    private Integer saveActivity(ActivityParam param, Integer businessId) {
        ActivityPO poParam=new ActivityPO();
        BeanUtils.copyProperties(param,poParam);
        //1.businessId
        poParam.setBusinessId(businessId);
        //2.status 0 待开始 1 已开始 2 已结束 enableStatus 0 启用 1 禁用
        poParam.setStatus(1);
        poParam.setEnableStatus(1);
        //3.createAt updateAt 两个时间
        poParam.setCreateAt(new Date());
        poParam.setUpdateAt(new Date());
        //4.手动转化 活动startTime endTime
        try {
            poParam.setStartDate(DateUtils.parseDate(param.getStartDate(),"yyyy-MM-dd HH:mm:ss"));
            poParam.setEndDate(DateUtils.parseDate(param.getEndDate(),"yyyy-MM-dd HH:mm:ss"));
        }catch (Exception e){
            log.error("时间格式化失败",e);
        }
        //5.rewardType 奖励类型  0优惠券 1积分 2实物商品 3其他
        poParam.setRewardType(0);
        //save写入数据库
        activityRepository.save(poParam);
        return poParam.getId();
    }

    private Integer getBusinessId() throws BusinessException {
        return checkAndGetBusinessId(getUserId());
    }

    public boolean isTargetConsumer(Integer userId, Integer activityId) {
        //1.利用活动id 获取活动详情 拿到targetConsumer目标人群的id 拿到活动关联商家
        ActivityPO po = activityRepository.getById(activityId);
        if (po==null){
            return false;
        }
        String targetCustomer = po.getTargetCustomer();
        if (targetCustomer==null){
            //说明 活动没有绑定任何目标人群 面向所有人
            return true;
        }
        Integer targetGroupId = Integer.valueOf(targetCustomer);
        Integer businessId = po.getBusinessId();
        //2.调用basic 只传递 userId 和活动的商家id businessId
        List<Integer> groupIds=basicApi.getUserGroupIds(userId,businessId);
        //3.根据basic的反馈结果 marketing 判断 是否应该展示
        if (groupIds!=null){
            //计算 活动的目标人群id 在不在 groupIds查询结果中
            return groupIds.contains(targetGroupId);
        }else{
            return false;
        }
    }

    public ActivityVO detail(Integer id) throws BusinessException {
        //1.读取 详情 po对象
        ActivityPO po = activityRepository.getById(id);
        Asserts.isTrue(po==null,new BusinessException("-2","活动详情不存在"));
        //2.组织远程调用 补充图片的url连接访问地址
        List<String> imgPic=getActivityImgUrls(id,700);
        ActivityVO vo=new ActivityVO();
        BeanUtils.copyProperties(po,vo);
        vo.setImgPics(imgPic);
        return vo;
    }
    @Value("${url.prefix}")
    private String urlPrefix;
    private List<String> getActivityImgUrls(Integer bizId, Integer bizType) {
        //attach包中的query
        AttachQuery query=new AttachQuery();
        query.setBusinessType(bizType);
        query.setBusinessId(bizId);
        //1.远程调用 拿到关联当前业务的所有图片
        List<AttachDTO> dtos = attachApi.getAttachInfoByParam(query);
        //2.解析每个图片元素 使用属性fileUuid拼接url前缀 获得图片url集合
        if (CollectionUtils.isNotEmpty(dtos)){
            return dtos.stream().map(dto->{
                //将dto的fileUuid拿出来 拼接前缀
                return urlPrefix+dto.getFileUuid();
            }).collect(Collectors.toList());
        }else{
            return null;
        }
    }

    public List<ActivityPO> getMarketingActivities(Integer storeId) {
        //select * from activity where shop_ids=? and marketing_type=1
        QueryWrapper<ActivityPO> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("shop_ids",storeId);
        queryWrapper.eq("marketing_type",1);
        return activityRepository.list(queryWrapper);
    }
}
